const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const routes = require("./routes");
const path = require("path");
const fs = require("fs");
const https = require('https');
const app = express();
const expressWinston = require('express-winston');
const dayjs = require('dayjs');
const morgan = require('morgan');
const {getAllFilesSync,logger} = require('./helpers/utilsHelper')
const {getProcessInfo} = require('./helpers/pm2Helper')
const {client,updateRedisValue,getRedisValue} = require('./helpers/redisHelper')
const {ifcTransformXkt} = require('./helpers/transformHelper')
var currentProcessId = process.pid; //当前进程id
const outputPath = path.join(__dirname, './bimFiles');
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

const options = {
  key: fs.readFileSync('server.key','utf8'),
  cert: fs.readFileSync('server.crt','utf8')
};
app.use(
  "/bimFiles",
  express.static(path.join(__dirname, "bimFiles"), {
    etag: true,
    lastModified: true,
  })
);


// 使用 Morgan 进行 HTTP 请求日志记录
app.use(morgan('combined'));

// 重写 console.log 方法，使用 winston 记录日志
console.log = function (...args) {
  logger.info(args.join(' '));
};

// 使用 express-winston 记录所有请求
app.use(expressWinston.logger({
  winstonInstance: logger,
  msg: (req, res) => `HTTP ${req.method} ${req.url} - 请求体参数: ${JSON.stringify(req.body)}
  - 请求头参数: ${JSON.stringify(req.headers)}`,
  colorize: true,
  meta: false
}));

app.use((req, res, next) => {
  const originalSend = res.send.bind(res);
  let isLogged = false;
  res.send = (body) => {   //重写send方法，每次响应多打印日志
    if (!isLogged) {
      // 获取响应状态码和结果
      const logEntry = `HTTP ${req.method} ${req.url} - 响应状态码: ${res.statusCode}\n响应结果: ${JSON.stringify(body)}\n\n`;
      logger.info(logEntry);
      isLogged = true;
    }
    return originalSend(body);
  };
  const lowercaseQueryParams = (query) => {  //去query参数的空格，且不区分大小写
    const result = {};
    Object.keys(query).forEach(key=>{
      const cleanedKey = key.replace(/\s+/g, '');
      const cleanedValue = req.query[key].replace(/\s+/g, '');
      result[cleanedKey.toLowerCase()] = cleanedValue;
    })
    return result;
  };
  req.query = lowercaseQueryParams(req.query);
  if(!req.query.apikey){
   return res.send({
      errmsg: "缺少参数apikey",
      result: -1,
    });
  }
  next();
});

app.use((err, req, res, next) => {
  console.log(`Error occurred: ${err.message}`, { stack: err.stack })
  logger.error(`Error occurred: ${err.message}`, { stack: err.stack });
  next()
});

app.use("/",routes);


client.on("error", (err) => {
  console.error("redis连接错误： ", err);
});

client.on("connect", () => {
  // console.log("置空redis的数据");
  if (!fs.existsSync(outputPath)) {  //无，则创建目录
    //判断是否有该目录
    fs.mkdirSync(outputPath, { recursive: true });
  }
  getProcessInfo("pid", (ids) => {     //每次重启多要清空redis数据
    if(currentProcessId==ids[0]){   //第一个进程用于执行该操作，防止多个进程执行
      console.log('所有进程id：',ids,'当前环境：',process.env.NODE_ENV=="development"?'开发':'生产');
      updateRedisValue("replace", [],()=>{},'bim');
      updateRedisValue("replace", ids, () => {}, "bim_processIds");
  }
});
  setInterval(() => {
    const currentDate = new Date();
    const currentHour = currentDate.getHours();
    const bimFilesPath=getAllFilesSync(outputPath)
    // 判断当前时间是否在凌晨1点
    if (currentHour === 1) {
      bimFilesPath.forEach(filePath=>{  //遍历所有文件
        fs.stat(filePath, (err, stats) => {
          // 获取文件的创建时间
          const creationTime = dayjs(new Date(stats.birthtime)).format('YYYY-MM-DD HH:mm:ss')
          if(!dayjs(creationTime).isSame(dayjs(), 'day')){//判断是否是当天,不是当天立马删除
            fs.unlink(filePath, err => {
                console.log('文件定时删除：',filePath,creationTime,err)
            })
          }
        })
      })
    }
    
    getRedisValue("bim", (value) => { //获取redis中key为bim的数据
      getProcessInfo("pid", (ids) => {
        if(currentProcessId==ids[0]) {
          console.log('redis中的数据：',JSON.stringify(value))
        }
      })
      if (Array.isArray(value)) {
        value.forEach((item) => {
          //状态为0且进程匹配才会去解析
          if (item.status == 0 && currentProcessId == item.processId) {
            //status为0为初始化状态，1为解析中,currentProcessId为当前进程id，item.processId为redis中的进程id
            //开始解析
            ifcTransformXkt(item);
          }
        });
      }
    });
  }, 10000);
});

https.createServer(options, app).listen(5055, () =>{
  getProcessInfo("pid", (ids) => {
    if(currentProcessId==ids[0]){
      console.log(`App listening on port 5055!`)
    }
  })
});
